﻿using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Ionic.Zlib;

namespace MyRTS
{
    public class fbx
    {
        public string path;
        public byte[] file;
        private byte[] Keydra = new byte[20];
        private byte[] Version = new byte[4];

        public string keydra;
        public int version;

        public List<Node> NodeList = new List<Node>();
        public List<TreeNode> TreeNodelist = new List<TreeNode>();


        public fbx(string p)
        {
            path = p;
            file = File.ReadAllBytes(p);
            Buffer.BlockCopy(file, 0, Keydra, 0, 20);
            Buffer.BlockCopy(file, 23, Version, 0, 4);
            keydra = System.Text.Encoding.UTF8.GetString(Keydra);
            version = BitConverter.ToInt32(Version,0);

            int counter = 27;

            try
            {
                while (counter < file.Length)
                {

                    Node n = new Node(counter, file,null);
                    NodeList.Add(n);
                    TreeNode m = new TreeNode();
                    m.Name = n.name;
                    TreeNodelist.Add(m);
                    counter = n.counter;
                }
            }
            catch
            {
                int poo = 0;
            }
            

            int l = 0;
        }
    }

    public class Nodl
    {
        public Node Node;
        public int level;

    }

    public class Node
    {
        private byte[] Offset = new byte[4];
        private byte[] ProNo = new byte[4];
        private byte[] ProListLen = new byte[4];
        private byte[] NameLen = new byte[1];
        private byte[] Name;

        public Node parrent;
        public string name;

        public int offset;

        public int counter;
        public List<Property> PropertyList = new List<Property>();
        public List<Node> NodeList = new List<Node>();



        public Node(int start, byte[] body,Node pa)
        {
            counter = start;
            Buffer.BlockCopy(body, start, Offset, 0, 4);
            offset = BitConverter.ToInt32(Offset, 0);
            counter += 4;
            Buffer.BlockCopy(body, counter, ProNo, 0, 4);
            int Proco=BitConverter.ToInt32(ProNo,0);
            counter += 4;
            Buffer.BlockCopy(body, counter, ProListLen, 0, 4);
            counter += 4;
            Buffer.BlockCopy(body, counter, NameLen, 0, 1);
            counter += 1;
            int temnamelenght;
            temnamelenght = NameLen[0];
            Name = new byte[temnamelenght];
            Buffer.BlockCopy(body, counter, Name, 0, Name.Length);
            name = System.Text.Encoding.UTF8.GetString(Name);
            counter += Name.Length;
            for (int i = 0; i < Proco; i++)
            {
                Property p = new Property(counter, body);
                PropertyList.Add(p);
                counter = p.counter;
            }
            try
            {
                while (counter < offset)
                {
                    Node n = new Node(counter, body,this);
                    NodeList.Add(n);
                    counter = n.counter;
                }
            }
            catch
            {
            }
            this.parrent = pa;
            int yuup = 0;


        }

        public Node zwrocN(List<Node> lis)
        {
            
            foreach (Node n in NodeList)
            {
                if (lis.Contains(n))
                {
                }
                else
                {
                    lis.Add(n.zwrocN(lis));
                }
                
            }

            return this;

        }

        public TreeNode zwroc3(TreeNode n)
        {
            TreeNode k=new TreeNode();
            k.Name=this.name;
            k.Text = this.name;
            foreach (Property p in this.PropertyList)
            {
                TreeNode lo = new TreeNode();
                if (p.Datas.Length < 100)
                {
                    lo.Text = "Type=" + p.type + "  Value ->" + p.Datas;
                }
                else
                {
                    lo.Text = "Type=" + p.type + "  Value ->" + p.Datas.Substring(0, 100); ;
                }
                k.Nodes.Add(lo);
            }
          
            foreach (Node no in this.NodeList)
            {
                no.zwroc3(k);
            }
            n.Nodes.Add(k);
            return n;
        }
      

        public void zwrocn2(List<Nodl> lis,int level)
        {
            Nodl li = new Nodl();
            li.Node = this;
            li.level = level;
            int l = level;
            lis.Add(li);
            l++;
            foreach (Node n in this.NodeList)
            {
                n.zwrocn2(lis,l);
            }

           // return this;
        }

    }
    public class Property
    {
        public byte[] Type = new byte[1];
        public string type;
        public byte[] Data;
        public string Datas="";
        public int enc;
        

        public int counter;


        public Property(int start, byte[] body)
        {
            counter = start;
            if (start == 12095)
            {
                int hjj = 0;
            }
            Buffer.BlockCopy(body, counter, Type, 0, 1);
            type = System.Text.Encoding.UTF8.GetString(Type);
            counter += 1;
            bool s = false;
            bool a = false;
            int lenght = 0;
            if (type == "I"||type=="F")
            {
                lenght = 4;
            }
            if (type == "D" || type == "L")
            {
                lenght = 8;
            }
            if (type == "Y")
            {
                lenght = 2;
            }
            if (type == "C")
            {
                lenght = 1;
            }
            if (type == "S"||type=="R")
            {
                s = true;
                
            }
            if (type == "f"||type=="i")
            {
                lenght = 4;
                a = true;
            }
            if (type == "d" || type == "l")
            {
                lenght = 8;
                a = true;
            }
            int slen = 0;
            if (s)
            {
                byte[] len = new byte[4];
                Buffer.BlockCopy(body, counter, len, 0, 4);
                slen = BitConverter.ToInt32(len, 0);
                counter += 4;
                Data = new byte[slen];
                Buffer.BlockCopy(body, counter, Data, 0, slen);

                if (type == "S")
                {
                    Datas = System.Text.Encoding.UTF8.GetString(Data);

                }
                counter += slen;
            }
            else
            {
                if (a)
                {
                    byte[] Arraylen = new byte[4];
                    Buffer.BlockCopy(body,counter,Arraylen,0,4);
                    counter+=4;
                    byte[] Encoding = new byte[4];
                    Buffer.BlockCopy(body,counter,Encoding,0,4);
                    counter+=4;
                    byte[] Comlen = new byte[4];
                    Buffer.BlockCopy(body,counter,Comlen ,0,4);
                    counter+=4;
                    int arl=BitConverter.ToInt32(Arraylen,0);
                    enc=BitConverter.ToInt32(Encoding,0);
                    int col=BitConverter.ToInt32(Comlen,0);
                   
                   
     
                    if (enc == 0)
                    {
                        Data = new byte[arl * lenght];
                        Buffer.BlockCopy(body, counter, Data, 0, arl * lenght);
                        for (int i = 0; i < arl * lenght; i = i + lenght)
                            {
                                byte[] tem=new byte[lenght];
                                for(int j=0;j<lenght;j++)
                                {
                                    tem[j]=Data[i+j];
                                }
                                double k = 0;
                                try
                                {
                                    k = BitConverter.ToDouble(tem, 0);
                                }
                                catch
                                {
                                    int lp = 0;
                                }
                                Datas += k.ToString() + "  ";
                            }
                            counter += arl * lenght;
                    }
                    else
                    {
                        byte[] tem = new byte[col];
                        
                        Buffer.BlockCopy(body, counter, tem, 0, col);
                        Data = ZlibStream.UncompressBuffer(tem);
                        for (int i = 0; i < Data.Length; i=i+lenght)
                        {
                            byte[] tempp=new byte[lenght];
                            for (int j = 0; j < lenght; j++)
                            {
                                tempp[j] = Data[i + j];
                            }
                            if (type == "i")
                            {
                                Datas += BitConverter.ToInt32(tempp, 0).ToString()+" ";
                            }
                            if (type == "d")
                            {
                                Datas += BitConverter.ToDouble(tempp, 0).ToString()+" ";
                            }
                           
                            if (type == "f")
                            {
                                Datas += BitConverter.ToSingle(tempp, 0).ToString()+" ";
                            }
                            if (type == "l")
                            {
                                Datas += BitConverter.ToInt64(tempp, 0).ToString()+" ";
                            }

                        }
                      //  Datas = BitConverter.ToInt64(Data, 0).ToString();
                        counter +=  col;
                    }
                }
                else
                {

                    Data = new byte[lenght];
                    Buffer.BlockCopy(body, counter, Data, 0, lenght);
                    if (type == "I")
                    {
                        Datas = BitConverter.ToInt32(Data, 0).ToString();
                    } 
                    if (type == "D")
                    {
                        Datas = BitConverter.ToDouble(Data, 0).ToString();
                    }
                    if (type == "Y")
                    {
                        Datas = BitConverter.ToInt16(Data, 0).ToString();
                    }
                    if (type == "F")
                    {
                        Datas = BitConverter.ToSingle(Data, 0).ToString();
                    }
                    if (type == "L")
                    {
                        Datas = BitConverter.ToInt64(Data, 0).ToString();
                    }
                    counter += lenght;
                }
            }
        }


    }
}
